﻿#pragma once

#include "AMain.h"
#include <string>
#include <vector>
#include <deque>
#include <stdexcept>
#include <any>
#include "exceptionhelper.h"
#include "../stringhelper.h"
#include "../tangible_filesystem.h"

namespace AutoPatcherAdmin
{
    class AMain : public System::Windows::Forms::Form
    {
    public:
        static const std::string PatchFileName;

        std::vector<std::string> ExcludeList = {"Thumbs.db"};

        std::vector<FileInformation*> OldList, NewList;
        std::deque<FileInformation*> UploadList;
        std::deque<FileInformation*> DownloadList;

    private:
        Stopwatch *_stopwatch = Stopwatch::StartNew();

    public:
        bool Completed = false;
    private:
        long long _currentBytes = 0;
        int _fileCount = 0, _currentCount = 0;

        FileInformation *_currentFile;

        long long _totalBytes = 0, _completedBytes = 0;

    public:
        virtual ~AMain()
        {
            delete _stopwatch;
            delete _currentFile;
            delete components;
            delete ClientTextBox;
            delete label1;
            delete label2;
            delete HostTextBox;
            delete label3;
            delete LoginTextBox;
            delete label4;
            delete PasswordTextBox;
            delete ProcessButton;
            delete progressBar1;
            delete ActionLabel;
            delete label5;
            delete progressBar2;
            delete SpeedLabel;
            delete label7;
            delete FileLabel;
            delete label8;
            delete SizeLabel;
            delete label10;
            delete ListButton;
            delete SourceLinkLabel;
            delete AllowCleanCheckBox;
            delete DownloadExistingButton;
            delete btnFixGZ;
        }

        AMain();

    private:
        void CompleteDownload();

        void CleanUp();
    public:
        bool NeedFile(const std::string &fileName);

        void GetOldFileList();

        std::vector<unsigned char> CreateNew();

        void GetNewFileList();

        bool InExcludeList(const std::string &fileName);

        void FixFilenameExtensions();

        bool NeedUpdate(FileInformation *info);

        DateTime TrimMilliseconds(DateTime dt);

        FileInformation *GetFileInformation(const std::string &fileName);

        std::vector<unsigned char> Download(const std::string &fileName);

        void Download(FileInformation *info);
    private:
        void BeginDownload();

    public:
        void Upload(FileInformation *info, std::vector<unsigned char> &raw, bool retry = true);

    private:
        void BeginUpload();

    public:
        void CheckDirectory(const std::string &directory);

        static std::vector<unsigned char> Decompress(std::vector<unsigned char> &raw);
        static std::vector<unsigned char> Compress(std::vector<unsigned char> &raw);

    private:
        void ListButton_Click(std::any sender, EventArgs *e);

        void ProcessButton_Click(std::any sender, EventArgs *e);

        void btnFixGZ_Click(std::any sender, EventArgs *e);

        void DownloadExistingButton_Click(std::any sender, EventArgs *e);

        void SourceLinkLabel_LinkClicked(std::any sender, LinkLabelLinkClickedEventArgs *e);

        void AMain_Load(std::any sender, EventArgs *e);



        /// <summary>
        /// Required designer variable.
        /// </summary>
        System::ComponentModel::IContainer *components = nullptr;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected:
        void Dispose(bool disposing) override;

        #pragma region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
    private:
        void InitializeComponent();

        #pragma endregion

        System::Windows::Forms::TextBox *ClientTextBox;
        System::Windows::Forms::Label *label1;
        System::Windows::Forms::Label *label2;
        System::Windows::Forms::TextBox *HostTextBox;
        System::Windows::Forms::Label *label3;
        System::Windows::Forms::TextBox *LoginTextBox;
        System::Windows::Forms::Label *label4;
        System::Windows::Forms::TextBox *PasswordTextBox;
        System::Windows::Forms::Button *ProcessButton;
        System::Windows::Forms::ProgressBar *progressBar1;
        System::Windows::Forms::Label *ActionLabel;
        System::Windows::Forms::Label *label5;
        System::Windows::Forms::ProgressBar *progressBar2;
        System::Windows::Forms::Label *SpeedLabel;
        System::Windows::Forms::Label *label7;
        System::Windows::Forms::Label *FileLabel;
        System::Windows::Forms::Label *label8;
        System::Windows::Forms::Label *SizeLabel;
        System::Windows::Forms::Label *label10;
        System::Windows::Forms::Button *ListButton;
        System::Windows::Forms::LinkLabel *SourceLinkLabel;
        System::Windows::Forms::CheckBox *AllowCleanCheckBox;
        System::Windows::Forms::Button *DownloadExistingButton;
        System::Windows::Forms::Button *btnFixGZ;
    };
}
